home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
LISP
/
XLISP
/
XLISP21S
/
sources
/
c
/
dosstuff
< prev
next >
Wrap
Text File
|
1992-04-25
|
27KB
|
1,202 lines
/* dosstuff.c - MS/DOS 16 bit compiler specific sources */
/* Handles Microsoft C (v4.0 or later), Turbo/Borland C (any version),
TopSpeed C (any version), and Zortech C (version 2 or later) in large
memory model. In addition handles Turbo/Borland C and TopSpeed C in
medium memory model, and the "x" (286 protected mode) model of Zortech C.*/
#include "xlisp.h"
#include "osdefs.h"
#include <dos.h>
#include <process.h>
#include <math.h>
#include <io.h>
#include <float.h>
#ifdef TIMES
#include <time.h>
#endif
#define LBSIZE 200
#ifdef __ZTC__
#ifdef DOS16RM
extern void * _cdecl D16SegAbsolute(long); /* undocumented, but necessary, function*/
unsigned _cdecl _stack = 48000; /* bigger stack in this case */
#else
unsigned _cdecl _stack = 16384; /* set up reasonable stack */
#endif
#endif
#ifdef __TURBOC__
unsigned _Cdecl _stklen = 16384; /* set up reasonable stack */
#ifdef MEDMEM
unsigned _Cdecl _heaplen = 4096; /* compress the near heap */
#endif
#endif
#ifdef MSC
/* MSC Doesn't define these */
#define MK_FP(seg,ofs) (((unsigned long)(seg)<<16) | (unsigned)(ofs))
#endif
/* external variables */
extern LVAL s_unbound,s_dosinput,true;
extern FILEP tfp;
/* exported variables */
int lposition;
/* local variables */
static char lbuf[LBSIZE];
static int lpos[LBSIZE];
static int lindex;
static int lcount;
/* forward declarations */
void NEAR xinfo(void);
void NEAR xflush(void);
int NEAR xgetc(void);
void NEAR xputc(int ch);
void NEAR setraw(void);
void NEAR unsetraw(void);
/* math error handler */
#ifdef __TSC__ /* Top Speed wants matherr to be function pointer! */
int newmatherr(struct exception *er)
#else
int CDECL matherr(struct exception *er)
#endif
{
char *emsg;
switch (er->type) {
case DOMAIN: emsg="domain"; break;
case OVERFLOW: emsg="overflow"; break;
case PLOSS: case TLOSS: emsg="inaccurate"; break;
case UNDERFLOW: return 1;
default: emsg="????"; break;
}
xlerror(emsg,cvflonum(er->arg1));
return 0; /* never happens */
}
/* osinit - initialize */
#ifdef MSC
extern unsigned _amblksiz;
#endif
VOID osinit(banner)
char *banner;
{
#ifdef MSC
/* _amblksiz = 16; */
#endif
#ifdef __TSC__
matherr = newmatherr;
#endif
setvbuf(stderr,NULL,_IOFBF,256);
if (*(char FAR *)MK_FP(_psp,0x19) != *(char FAR *)MK_FP(_psp,0x1a))
redirectout = TRUE;
if (*(char FAR *)MK_FP(_psp,0x18) != *(char FAR *)MK_FP(_psp,0x1a))
redirectin = TRUE;
fprintf(stderr,"%s\n",banner);
lposition = 0;
lindex = 0;
lcount = 0;
setraw();
#if defined( __TURBOC__) || defined(MSC) || defined(__TSC__)
/* let fp overflow pass and domain errors */
_control87(EM_OVERFLOW|EM_INVALID,EM_OVERFLOW|EM_INVALID);
#endif
#ifdef __TURBOC__
/* force raw mode for stderr */
stderr->flags |= _F_BIN;
#endif
}
/* osfinish - clean up before returning to the operating system */
VOID osfinish()
{
unsetraw();
}
/* xoserror - print an error message */
VOID xoserror(msg)
char *msg;
{
fprintf(stderr,"error: %s\n",msg);
}
/* osrand - return next random number in sequence */
long osrand(rseed)
long rseed;
{
long k1;
/* make sure we don't get stuck at zero */
if (rseed == 0L) rseed = 1L;
/* algorithm taken from Dr. Dobbs Journal, November 1985, page 91 */
k1 = rseed / 127773L;
if ((rseed = 16807L * (rseed - k1 * 127773L) - k1 * 2836L) < 0L)
rseed += 2147483647L;
/* return a random number between 0 and MAXFIX */
return rseed;
}
#ifdef FILETABLE
int truename(char *name, char *rname)
{
union REGS regs;
#ifndef MEDMEM
struct SREGS sregs;
#endif
int i;
char *cp;
int drive; /* drive letter */
char pathbuf[FNAMEMAX+1]; /* copy of path part of name */
char curdir[FNAMEMAX+1]; /* current directory of drive */
char *fname; /* pointer to file name part of name */
/* use backslashes consistantly */
for (cp = name; (cp = strchr(cp, '/')) != NULL; *cp = '\\') ;
/* parse any drive specifier */
if ((cp = strrchr(name, ':')) != NULL) {
if (cp != name+1 || !isalpha(*name)) return FALSE;
drive = toupper(*name);
name = cp+1; /* name now excludes drivespec */
}
else {
regs.h.ah = 0x19; /* get current disk */
intdos(®s, ®s);
drive = regs.h.al + 'A';
}
/* check for absolute path (good news!) */
if (*name == '\\') {
sprintf(rname,"%c:%s",drive,name);
}
else {
strcpy(pathbuf, name);
if ((cp = strrchr(pathbuf, '\\')) != NULL) { /* path present */
cp[1] = 0;
fname = strrchr(name, '\\') + 1;
}
else {
pathbuf[0] = 0;
fname = name;
}
/* get the current directory of the selected drive */
regs.h.ah = 0x47;
regs.h.dl = drive + 1 - 'A';
#ifdef MEDMEM
regs.x.si = (unsigned) curdir;
intdos(®s, ®s);
#else
regs.x.si = (unsigned) FP_OFF(curdir);
sregs.ds = (unsigned) FP_SEG(curdir);
intdosx(®s, ®s, &sregs);
#endif
if (regs.x.cflag != 0) return FALSE; /* invalid drive */
/* peel off "..\"s */
while (strncmp(pathbuf, "..\\", 3) == 0) {
if (*curdir == 0) return FALSE; /* already at root */
strcpy(pathbuf, pathbuf+3);
if ((cp=strrchr(curdir, '\\')) != NULL)
*cp = 0; /* peel one depth of directories */
else
*curdir = 0; /* peeled back to root */
}
/* allow for a ".\" */
if (strncmp(pathbuf, ".\\", 2) == 0)
strcpy(pathbuf, pathbuf+2);
/* final name is drive:\curdir\pathbuf\fname */
if (strlen(pathbuf)+strlen(curdir)+strlen(fname)+4 > FNAMEMAX)
return FALSE;
if (*curdir)
sprintf(rname, "%c:\\%s\\%s%s", drive, curdir, pathbuf, fname);
else
sprintf(rname, "%c:\\%s%s", drive, pathbuf, fname);
}
/* lowercase the whole string */
for (cp = rname; (i = *cp) != 0; cp++) {
if (isupper(i)) *cp = tolower(i);
}
return TRUE;
}
extern void gc(void);
LOCAL int NEAR getslot(VOID)
{
int i=0;
for (; i < FTABSIZE; i++) /* look for available slot */
if (filetab[i].fp == NULL) return i;
gc(); /* is this safe??????? */
for (i=0; i < FTABSIZE; i++) /* try again -- maybe one has been freed */
if (filetab[i].fp == NULL) return i;
xlfail("too many open files");
return 0; /* never returns */
}
FILEP osaopen(const char *name, const char *mode)
{
int i=getslot();
char namebuf[FNAMEMAX+1];
FILE *fp;
if (!truename((char *)name, namebuf))
strcpy(namebuf, name); /* should not happen */
if ((filetab[i].tname = malloc(strlen(namebuf)+1)) == NULL) {
free(filetab[i].tname);
xlfail("insufficient memory");
}
if ((fp = fopen(name,mode)) == NULL) {
free(filetab[i].tname);
return CLOSED;
}
filetab[i].fp = fp;
strcpy(filetab[i].tname, namebuf);
return i;
}
FILEP osbopen(const char *name, const char *mode)
{
char bmode[10];
strcpy(bmode,mode); strcat(bmode,"b");
return osaopen(name, bmode);
}
VOID osclose(FILEP f)
{
fclose(filetab[f].fp);
free(filetab[f].tname);
filetab[f].tname = NULL;
filetab[f].fp = NULL;
}
#else
/* osbopen - open a binary file */
FILE * CDECL osbopen(const char *name, const char *mode)
{
char bmode[10];
strcpy(bmode,mode); strcat(bmode,"b");
return (fopen(name,bmode));
}
#endif
#ifdef PATHNAMES
/* ospopen - open for reading using a search path */
FILEP ospopen(char *name, int ascii)
{
FILEP fp;
char *path = getenv(PATHNAMES);
char *newnamep;
char ch;
char newname[256];
/* don't do a thing if user specifies explicit path */
if (strchr(name,'/') != NULL && strchr(name, '\\') != NULL)
#ifdef FILETABLE
return (ascii? osaopen: osbopen)(name,"r");
#else
return fopen(name,(ascii? "r": "rb"));
#endif
do {
if (*path == '\0') /* no more paths to check */
/* check current directory just in case */
#ifdef FILETABLE
return (ascii? osaopen: osbopen)(name,"r");
#else
return fopen(name,(ascii? "r": "rb"));
#endif
newnamep = newname;
while ((ch=*path++) != '\0' && ch != ';' && ch != ' ')
*newnamep++ = ch;
if (ch == '\0') path--;
if (newnamep != newname &&
*(newnamep-1) != '/' && *(newnamep-1) != '\\')
*newnamep++ = '/'; /* final path separator needed */
*newnamep = '\0';
strcat(newname, name);
#ifdef FILETABLE
fp = (ascii? osaopen: osbopen)(newname,"r");
#else
fp = fopen(newname, ascii? "r": "rb");
#endif
} while (fp == CLOSED); /* not yet found */
return fp;
}
#endif
/* rename argument file as backup, return success name */
/* For new systems -- if cannot do it, just return TRUE! */
int renamebackup(char *filename) {
char *bufp, ch=0;
strcpy(buf, filename); /* make copy with .bak extension */
bufp = &buf[strlen(buf)]; /* point to terminator */
while (bufp > buf && (ch = *--bufp) != '.' && ch != '/' && ch != '\\') ;
if (ch == '.') strcpy(bufp, ".bak");
else strcat(buf, ".bak");
remove(buf);
return !rename(filename, buf);
}
/* ostgetc - get a character from the terminal */
int ostgetc()
{
int ch;
union REGS regs;
struct SREGS segregs;
/* check for a buffered character */
if (lcount-- > 0)
return (lbuf[lindex++]);
/* get an input line */
if (getvalue(s_dosinput) != NIL && !redirectin && !redirectout) {
fflush(stderr);
lindex = 2;
lbuf[0] = LBSIZE - 2;
regs.x.ax = 0x0A00;
regs.x.dx = FP_OFF(lbuf);
segregs.ds = FP_SEG(lbuf);
intdosx(®s,®s,&segregs);
putchar('\n');
lcount = lbuf[1];
lbuf[lcount+2] = '\n';
if (tfp!=CLOSED) OSWRITE(&lbuf[2],1,lcount+1,tfp);
lposition = 0;
return (lbuf[lindex++]);
}
else {
for (lcount = 0; ; )
switch (ch = xgetc()) {
case '\r':
case '\n':
lbuf[lcount++] = '\n';
xputc('\r'); xputc('\n'); lposition = 0;
if (tfp!=CLOSED) OSWRITE(lbuf,1,lcount,tfp);
lindex = 0; lcount--;
return (lbuf[lindex++]);
case '\010':
case '\177':
if (lcount) {
lcount--;
while (lposition > lpos[lcount]) {
xputc('\010'); xputc(' '); xputc('\010');
lposition--;
}
}
break;
case '\032':
xflush();
return (EOF);
default:
if (ch == '\t' || (ch >= 0x20 && ch < 0x7F)) {
lbuf[lcount] = ch;
lpos[lcount] = lposition;
if (ch == '\t')
do {
xputc(' ');
} while (++lposition & 7);
else {
xputc(ch); lposition++;
}
lcount++;
}
else {
xflush();
switch (ch) {
case '\003': xltoplevel(); /* control-c */
case '\007': xlcleanup(); /* control-g */
case '\020': xlcontinue(); /* control-p */
case '\032': return (EOF); /* control-z */
case '\024': xinfo(); /* control-t */
return ostgetc();
default: return (ch);
}
}
}}
}
/* ostputc - put a character to the terminal */
VOID ostputc(ch)
int ch;
{
/* check for control characters */
oscheck();
/* output the character */
if (ch == '\n') {
xputc('\r'); xputc('\n');
lposition = 0;
}
else if (ch == '\t')
do { xputc(' '); } while (++lposition & 7);
else {
xputc(ch);
lposition++;
}
/* output the character to the transcript file */
if (tfp!=CLOSED)
OSPUTC(ch,tfp);
}
/* osflush - flush the terminal input buffer */
VOID osflush()
{
lindex = lcount = lposition = 0;
}
/* oscheck - check for control characters during execution */
VOID oscheck()
{
int ch;
if (!redirectin && (ch = (bdos(6,0xFF,0) & 0xff)) != 0)
switch (ch) {
case '\002': /* control-b */
xflush();
xlbreak("BREAK",s_unbound);
break;
case '\003': /* control-c */
xflush();
xltoplevel();
break;
case '\023': /* control-s */
xgetc(); /* paused -- get character and toss */
break;
case '\024': /* control-t */
xinfo();
break;
}
}
/* xinfo - show information on control-t */
static VOID NEAR xinfo()
{
extern long nfree;
extern int gccalls;
extern long total;
sprintf(buf,"\n[ Free: %ld, GC calls: %d, Total: %ld ]",
nfree,gccalls,total);
errputstr(buf);
fflush(stderr);
}
/* xflush - flush the input line buffer and start a new line */
static VOID NEAR xflush()
{
osflush();
ostputc('\n');
}
/* xgetc - get a character from the terminal without echo */
static int NEAR xgetc()
{
fflush(stderr);
if (!redirectin)
return (bdos(7,0,0) & 0xFF);
else {
#ifdef __TURBOC__
char temp[1];
_read(2, temp, 1);
#else
#if defined(MSC) || defined(__TSC__)
char temp[1];
int dummy;
_dos_read(2, temp, 1, &dummy);
#else
char temp[1];
read(2, temp, 1);
#endif
#endif
return temp[0];
}
}
/* xputc - put a character to the terminal */
static void NEAR xputc(ch)
int ch;
{
fputc(ch,stderr);
if (ch == '\n') fflush(stderr);
}
#ifdef OVERLAY
/* Ralf Brown's SPAWNO package */
#ifdef __TSC__
int cdecl spawnvo(const char *overlay_path, const char *name, va_list args) ;
#else
#include "spawno.h"
#endif
#endif
/* xsystem - execute a system command */
LVAL xsystem()
{
char *cmd[4];
int ok;
cmd[0] = getenv("COMSPEC");
if (moreargs()) {
cmd[1] = "/c";
#ifdef MEDMEM
MEMCPY(buf, getstring(xlgastring()), STRMAX);
cmd[2] = buf;
#else
cmd[2] = getstring(xlgastring());
#endif
cmd[3] = NULL;
xllastarg();
}
else {
cmd[1] = NULL;
}
unsetraw();
#ifdef OVERLAY
ok = spawnvo("/",cmd[0], cmd);
#else
ok = spawnv(P_WAIT,cmd[0], cmd);
#endif
setraw();
return (ok == 0 ? true : cvfixnum((FIXTYPE)errno));
}
/* xgetkey - get a key from the keyboard */
LVAL xgetkey()
{
xllastarg();
return (cvfixnum((FIXTYPE)xgetc()));
}
static unsigned savestate;
static unsigned char savebrk;
#ifdef GRAPHICS
static unsigned char origmode;
static unsigned ourmode1=0, ourmode2=0;
static VOID NEAR setgmode(int ax, int bx)
{
union REGS regs;
regs.x.ax = ax;
regs.x.bx = bx;
int86(0x10, ®s, ®s);
}
#endif
/* setraw -- set raw mode */
static VOID NEAR setraw(void)
{
union REGS regs;
regs.x.ax = 0x4400; /* get device status */
regs.x.bx = 2;
intdos(®s,®s);
regs.h.dh = 0;
savestate = regs.x.dx;
regs.x.ax = 0x4401;
regs.h.dl |= 0x20;
intdos(®s,®s);
regs.x.ax = 0x3300; /* get ctrl-break status */
intdos(®s,®s);
savebrk = regs.h.dl;
regs.x.ax = 0x3301;
regs.h.dl = 0;
intdos(®s,®s);
#ifdef GRAPHICS
regs.x.ax = 0x0f00; /* get mode */
int86(0x10, ®s, ®s);
origmode = regs.h.al;
if (ourmode1 != 0) /* mode was changed -- use it */
setgmode(ourmode1,ourmode2);
#endif
}
/* unsetraw -- restore original mode */
static VOID NEAR unsetraw(void)
{
union REGS regs;
regs.x.ax = 0x4401;
regs.x.bx = 2;
regs.x.dx = savestate;
intdos(®s,®s);
regs.x.ax = 0x3301;
regs.h.dl = savebrk;
intdos(®s,®s);
#ifdef GRAPHICS
if ((ourmode1 !=0) && (ourmode2 != origmode))
setgmode(origmode,0);
#endif
}
/* ossymbols - enter os specific symbols */
VOID ossymbols()
{
}
#ifdef GRAPHICS
static union REGS regin, regout;
static int xpos=0, ypos=0;
static int Xmax=-1, Ymax=-1;
static unsigned char drawvalue=15;
/* function goto-xy which set/obtains cursor position */
LVAL xgotoxy()
{
union REGS regs;
FIXTYPE x, y;
LVAL oldpos;
#ifdef DOS16RM /* kludge for 80286 protected mode */
unsigned char *basemem = D16SegAbsolute(0L);
#endif
fflush(stderr);
regs.h.ah = 0x3; /* get old position */
regs.h.bh = 0;
int86(0x10, ®s, ®s);
oldpos = cons(cvfixnum((FIXTYPE)regs.h.dl),
cons(cvfixnum((FIXTYPE)regs.h.dh),NIL));
if (moreargs()) {
x = getfixnum(xlgafixnum());
y = getfixnum(xlgafixnum());
xllastarg();
if (x < 0) x = 0; /* check for in bounds */
#ifdef DOS16RM
else if (x >= *(unsigned int FAR *)(basemem+0x44a))
x = *(unsigned int FAR *)(basemem+0x44a) - 1;
#else
else if (x >= *(unsigned int FAR *) 0x44aL)
x = *(unsigned int FAR *) 0x44aL - 1;
#endif
if (y < 0) y = 0;
#ifdef DOS16RM
else if (*(basemem+0x484) != 0) {
if (y > *(basemem+0x484))
y = *(basemem+0x484);
}
#else
else if (*(unsigned char FAR *) 0x484L != 0) {
if (y > *(unsigned char FAR *) 0x484L)
y = *(unsigned char FAR *) 0x484L;
}
#endif
else if (y > 24) y = 24;
regs.h.ah = 0x2; /* set new position */
regs.h.dl = x;
regs.h.dh = y;
regs.h.bh = 0;
int86(0x10, ®s, ®s);
lposition = (int)x;
}
return oldpos;
}
LVAL xcls() /* clear the screen */
{
union REGS regs;
int xsize, ysize, attrib;
#ifdef DOS16RM /* kludge for 80286 protected mode */
unsigned char *basemem = D16SegAbsolute(0L);
#endif
fflush(stderr);
lposition = 0;
#ifdef DOS16RM
xsize = *(unsigned int FAR *)(basemem+0x44a);
ysize = (*(basemem+0x484) != 0 ? *(basemem+0x484) : 24);
attrib = (ourmode1 > 3 ? 0 :
*(unsigned char FAR *)D16SegAbsolute(0xb8001L));
#else
xsize = *(unsigned int FAR *) 0x44aL;
ysize = (*(unsigned char FAR *) 0x484L != 0 ?
*(unsigned char FAR *)0x484L : 24);
attrib = (ourmode1 > 3 ? 0 : *(unsigned char FAR *)0xb8000001L);
#endif
regs.x.ax = 0x0600;
regs.h.bh = attrib;
regs.x.cx = 0;
regs.h.dh = ysize;
regs.h.dl = xsize;
int86(0x10, ®s, ®s);
regs.h.ah =0x2; /* home cursor */
regs.x.dx = 0;
regs.h.bh = 0;
int86(0x10, ®s, ®s);
return NIL;
}
LVAL xcleol() /* clear to end of line */
{
union REGS regs;
fflush(stderr);
regs.h.ah = 0x3; /* get old position */
regs.h.bh = 0;
int86(0x10, ®s, ®s); /* x position in regs.h.dl, y in regs.h.dh */
lposition = regs.h.dl; /* just to be sure */
regs.x.cx = regs.x.dx;
#ifdef DOS16RM
regs.h.dl = (*(unsigned int FAR *)D16SegAbsolute(0x44aL)) -1;/* x size */
regs.h.bh = (ourmode1 > 3 ? 0 :
*(unsigned char FAR *)D16SegAbsolute(0xb8001L)); /* atrrib*/
#else
regs.h.dl = *(unsigned int FAR *) 0x44aL -1; /* x size */
regs.h.bh = (ourmode1 > 3 ? 0 : *(unsigned char FAR *)0xb8000001L); /* atrrib*/
#endif
regs.x.ax = 0x0600; /* scroll region */
int86(0x10, ®s, ®s);
return NIL;
}
static LVAL NEAR draw(int x, int y, int x2, int y2)
{
int xStep,yStep,xDist,yDist;
int i, t8, t9, t10;
fflush(stderr);
if ((x < 0) | (x > Xmax) | (y < 0) | (y > Ymax) |
(x2 < 0)| (x2 > Xmax) | (y2 < 0) | (y2 > Ymax))
return (NIL);
x -= x2; /* cvt to distance and screen coordiate (right hand) */
y2 = Ymax - y2;
y = (Ymax - y) - y2;
if (x < 0) { /* calculate motion */
xStep = -1;
xDist = -x;
}
else {
xStep = 1;
xDist = x;
}
if (y < 0) {
yStep = -1;
yDist = -y;
}
else {
yStep = 1;
yDist = y;
}
regin.x.ax = drawvalue + 0x0c00; /* write graphic pixel command */
regin.x.cx = x2; /* initial coordinates */
regin.x.dx = y2;
int86(0x10,®in,®out); /* initial draw */
if (yDist == 0) {
i = xDist;
while (i--) {
regin.x.cx += xStep;
int86(0x10,®in,®out);
}
}
else if (xDist == yDist) {
i = xDist;
while (i--) {
regin.x.cx += xStep;
regin.x.dx += yStep;
int86(0x10,®in,®out);
}
}
else if (xDist == 0) {
i = yDist;
while (i--) {
regin.x.dx += yStep;
int86(0x10,®in,®out);
}
}
else if (xDist > yDist) {
t8 = 2*yDist;
t10 = 2*yDist - xDist;
t9 = 2*(yDist - xDist);
i = xDist;
while (i--) {
regin.x.cx += xStep;
if (t10 < 0) {
t10 += t8;
}
else {
regin.x.dx += yStep;
t10 += t9;
}
int86(0x10,®in,®out);
}
}
else {
t8 = 2*xDist;
t10 = 2*xDist - yDist;
t9 = 2*(xDist - yDist);
i = yDist;
while (i--) {
regin.x.dx += yStep;
if (t10 < 0) {
t10 += t8;
}
else {
regin.x.cx += xStep;
t10 += t9;
}
int86(0x10,®in,®out);
}
}
return (true);
}
/* xmode -- set display mode */
/* called with either ax contents, or ax,bx,xsize,ysize */
LVAL xmode()
{
int nmode1, nmode2;
LVAL arg;
arg = xlgafixnum();
nmode1 = (int) getfixnum(arg);
if (moreargs()) {
arg = xlgafixnum();
nmode2 = (int) getfixnum(arg);
arg = xlgafixnum();
Xmax = (int) getfixnum(arg) - 1; /* max x coordinate */
arg = xlgafixnum();
Ymax = (int) getfixnum(arg) - 1; /* max y coordinate */
xllastarg();
}
else {
nmode2 = 0;
switch (nmode1) {
case 0: case 1: case 2: case 3:
Xmax = Ymax = -1; /* not a graphic mode */
break;
case 4:
case 5:
case 13:
case 19: Xmax = 319;
Ymax = 199;
break;
case 6:
case 14: Xmax = 639;
Ymax = 199;
break;
case 16: Xmax = 639;
Ymax = 349;
break;
case 17:
case 18: Xmax = 639; /* added VGA mode */
Ymax = 479;
break;
default: return NIL; /* failed */
}
}
ourmode1 = nmode1;
ourmode2 = nmode2;
setgmode(ourmode1,ourmode2); /* set mode */
return (true);
}
/* xcolor -- set color */
LVAL xcolor()
{
LVAL arg;
arg = xlgafixnum();
xllastarg();
drawvalue = (char) getfixnum(arg);
return (arg);
}
/* xdraw -- absolute draw */
LVAL xdraw()
{
LVAL arg = true;
int newx, newy;
while (moreargs()) {
arg = xlgafixnum();
newx = (int) getfixnum(arg);
arg = xlgafixnum();
newy = (int) getfixnum(arg);
arg = draw(xpos,ypos,newx,newy);
xpos = newx;
ypos = newy;
}
return (arg);
}
/* xdrawrel -- absolute draw */
LVAL xdrawrel()
{
LVAL arg = true;
int newx, newy;
while (moreargs()) {
arg = xlgafixnum();
newx = xpos + (int) getfixnum(arg);
arg = xlgafixnum();
newy = ypos + (int) getfixnum(arg);
arg = draw(xpos,ypos,newx,newy);
xpos = newx;
ypos = newy;
}
return (arg);
}
/* xmove -- absolute move, then draw */
LVAL xmove()
{
LVAL arg;
arg = xlgafixnum();
xpos = (int) getfixnum(arg);
arg = xlgafixnum();
ypos = (int) getfixnum(arg);
return (xdraw());
}
/* xmoverel -- relative move */
LVAL xmoverel()
{
LVAL arg;
arg = xlgafixnum();
xpos += (int) getfixnum(arg);
arg = xlgafixnum();
ypos += (int) getfixnum(arg);
return (xdrawrel());
}
#endif
#ifdef TIMES
/* For some reason, every compiler is different ... */
#if defined(MSC) || defined(__TSC__)
unsigned long ticks_per_second() { return((unsigned long) CLK_TCK); }
unsigned long run_tick_count()
{
return((unsigned long) clock()); /* Real time in MSDOS */
}
unsigned long real_tick_count()
{ /* Real time */
return((unsigned long) clock());
}
LVAL xtime()
{
LVAL expr,result;
unsigned long tm;
/* get the expression to evaluate */
expr = xlgetarg();
xllastarg();
tm = run_tick_count();
result = xleval(expr);
tm = run_tick_count() - tm;
sprintf(buf, "The evaluation took %.2f seconds.\n",
((double)tm) / ticks_per_second());
trcputstr(buf);
fflush(stderr);
return(result);
}
#endif
#ifdef __ZTC__
unsigned long ticks_per_second() { return((unsigned long) CLK_TCK); }
unsigned long run_tick_count()
{
return((unsigned long) clock()); /* Real time in MSDOS */
}
unsigned long real_tick_count()
{ /* Real time */
return((unsigned long) clock());
}
LVAL xtime()
{
LVAL expr,result;
double tm;
/* get the expression to evaluate */
expr = xlgetarg();
xllastarg();
tm = run_tick_count();
result = xleval(expr);
tm = (run_tick_count() - tm) / CLK_TCK ;
sprintf(buf, "The evaluation took %.2f seconds.\n", tm);
trcputstr(buf);
fflush(stderr);
return(result);
}
#endif
#ifdef __TURBOC__
/* We want to cheat here because ticks_per_second would have to be rounded */
#define OURTICKS 1000
unsigned long ticks_per_second() {
return((unsigned long) OURTICKS);
}
unsigned long run_tick_count()
{ /*Real time in MSDOS*/
return((unsigned long) ((OURTICKS/CLK_TCK)*clock()));
}
unsigned long real_tick_count()
{ /* Real time */
return((unsigned long) ((OURTICKS/CLK_TCK)*clock()));
}
LVAL xtime()
{
LVAL expr,result;
unsigned long tm;
/* get the expression to evaluate */
expr = xlgetarg();
xllastarg();
tm = run_tick_count();
result = xleval(expr);
tm = run_tick_count() - tm;
sprintf(buf, "The evaluation took %.2f seconds.\n",
((double)tm) / ticks_per_second());
trcputstr(buf);
fflush(stderr);
return(result);
}
#endif
LVAL xruntime() {
xllastarg();
return(cvfixnum((FIXTYPE) run_tick_count()));
}
LVAL xrealtime() {
xllastarg();
return(cvfixnum((FIXTYPE) real_tick_count()));
}
#endif